import os
import subprocess
import sys

import compare_meta_cmd
import compare_system
import install_db
import upgrade
from compare_data import CompareData
from log import WriteLog


class UpgradeScene:
    def __init__(self, *args, **kwargs):
        self.up = upgrade.Upgrade(**kwargs)
        self.log = WriteLog()
        self.hostnames = args
        self.prefixPort = kwargs['prefixPort']
        self.tpcc_path = kwargs['tpcc_path']
        self.upgrade_user = ''
        self.direct_user = ''
        self.upgrade_port = ''
        self.direct_port = ''
        self.upgrade = dict()
        self.direct = dict()
        self.hosts = dict()
        self.ins = None
        self.up_tpcc_pname = 'upgrade_props.pg'
        self.di_tpcc_pname = 'direct_props.pg'
        self.cda = None

    def set_params(self, up_user_prefix, di_user_prefix):
        self.upgrade_user = subprocess.getoutput(
            f'ls /home|grep {up_user_prefix}')
        self.direct_user = subprocess.getoutput(
            f'ls /home|grep {di_user_prefix}')
        self.upgrade_port = subprocess.getoutput(
            f"grep -w 'port =' {self.up.db_root_path}/{self.upgrade_user}/"
            f"cluster/dn1/postgresql.conf|awk '{{print $3}}'")
        self.direct_port = subprocess.getoutput(
            f"grep -w 'port =' {self.up.db_root_path}/{self.direct_user}/"
            f"cluster/dn1/postgresql.conf|awk '{{print $3}}'")

        self.upgrade = {'ip': self.up.ipaddress,
                        'username': self.upgrade_user,
                        'pwd': self.up.passwd,
                        'db_name': 'postgres',
                        'db_port': self.upgrade_port,
                        'db_version': 'upgrade',
                        'db_env': f'/home/{self.upgrade_user}/gaussdb.bashrc'}
        self.direct = {'ip': self.up.ipaddress,
                       'username': self.direct_user,
                       'pwd': self.up.passwd,
                       'db_name': 'postgres',
                       'db_port': self.direct_port,
                       'db_version': 'direct',
                       'db_env': f'/home/{self.direct_user}/gaussdb.bashrc'}

    def install(self, user_prefix, db_version, ftp_path,
                cm_flag=False):
        self.log.print_log('安装数据库')
        in_params = dict()
        in_params['rootpasswd'] = self.up.passwd
        in_params['userpasswd'] = self.up.passwd
        in_params['dburpasswd'] = self.up.passwd
        in_params['report_db_passwd'] = 'sua@222*w'
        in_params['report_db_host'] = 'xx.xx.xx.xx'
        in_params['report_user'] = 'report0517'
        in_params['report_db'] = 'autotest_report'
        in_params['report_db_port'] = '50517'
        in_params['func_user_prefix'] = user_prefix
        in_params['prefixPort'] = self.prefixPort
        in_params['db_root_path'] = self.up.db_root_path
        in_params['pkg_root_path'] = self.up.pkg_root_path
        in_params['db_version'] = db_version
        in_params['ftp_path'] = ftp_path

        self.ins = install_db.InstallDb(**in_params)
        self.hosts = dict(
            zip((self.up.ipaddress, self.up.ipaddress_std1,
                 self.up.ipaddress_std2),
                self.hostnames))
        self.ins.clean_env(self.up.ipaddress, self.up.ipaddress_std1,
                           self.up.ipaddress_std2)
        self.ins.prepare_user()
        self.ins.get_pkg()
        self.ins.prepare_xml(**self.hosts)
        if cm_flag:
            self.ins.update_xml_for_cm(**self.hosts)
        self.ins.preinstall()
        self.ins.install(self.up.ipaddress_std2)
        self.ins.set_param(*self.hosts.keys())
        self.ins.get_db_vesion(self.up.ipaddress_std2)

    def compare_sys(self):
        cw = compare_system.CompareWrite()
        data_dict = {'system_table': [],
                     'system_view': [],
                     'meta_cmd': []}

        self.log.print_log('系统表校验，先检验表名，再校验表结构，最后校验表内容')
        command = 'select distinct (schemaname,tablename) as a ' \
                  'from pg_tables order by a;'
        pg_tables_1 = cw.conn_and_run(command, True, **self.upgrade).replace(
            self.upgrade['username'], '').splitlines()
        pg_tables_2 = cw.conn_and_run(command, True, **self.direct).replace(
            self.direct['username'], '').splitlines()
        same, diff = cw.compare(pg_tables_1, pg_tables_2,
                                self.upgrade['db_version'],
                                self.direct['db_version'],
                                command,
                                self.upgrade_user,
                                self.direct_user)
        data_dict['system_table'].append(diff)
        for st in same:
            if ',' in st:
                tmp = st[2:-1].split(',')
                command = f'\\d+ {tmp[0]}.{tmp[1]}'
                pg_tables_1 = cw.conn_and_run(
                    command, True, **self.upgrade).replace(
                    self.upgrade['username'], '').splitlines()
                pg_tables_2 = cw.conn_and_run(
                    command, True, **self.direct).replace(
                    self.direct['username'], '').splitlines()
                s1, d1 = cw.compare(pg_tables_1, pg_tables_2,
                                    self.upgrade['db_version'],
                                    self.direct['db_version'],
                                    command,
                                    self.upgrade_user,
                                    self.direct_user)
                data_dict['system_table'].append(d1)

        self.log.print_log('系统视图校验，先检验视图名，再校验视图结构，最后校验视图内容')
        command = 'select distinct (schemaname,viewname) as a ' \
                  'from pg_views order by a;'
        pg_tables_1 = cw.conn_and_run(command, True, **self.upgrade).replace(
            self.upgrade['username'], '').splitlines()
        pg_tables_2 = cw.conn_and_run(command, True, **self.direct).replace(
            self.direct['username'], '').splitlines()
        same, diff = cw.compare(pg_tables_1, pg_tables_2,
                                self.upgrade['db_version'],
                                self.direct['db_version'],
                                command,
                                self.upgrade_user,
                                self.direct_user)
        data_dict['system_view'].append(diff)
        for st in same:
            if ',' in st:
                tmp = st[2:-1].split(',')
                command = f'\\d+ {tmp[0]}.{tmp[1]}'
                pg_tables_1 = cw.conn_and_run(
                    command, True, **self.upgrade).replace(
                    self.upgrade['username'], '').splitlines()
                pg_tables_2 = cw.conn_and_run(
                    command, True, **self.direct).replace(
                    self.direct['username'], '').splitlines()
                s1, d1 = cw.compare(pg_tables_1, pg_tables_2,
                                    self.upgrade['db_version'],
                                    self.direct['db_version'],
                                    command,
                                    self.upgrade_user,
                                    self.direct_user)
                data_dict['system_view'].append(d1)

        num = 1
        f_path = os.path.join(os.getcwd(), 'log', 'compare',
                              self.upgrade["db_version"],
                              'system_table.diff')
        context = f'{self.upgrade["db_version"]} vs ' \
            f'直接安装{self.direct["db_version"]}\n\n'
        for row in data_dict.get('system_table', None):
            cmd = row.get('cmd', None)
            diff = row.get('diff', None)
            if len(diff) > 0:
                context += cmd + '\n'
                for j in diff:
                    context += str(j) + '\n'
                context += '\n\n'
        self.log.write_file_with_part(f_path, num, context)
        self.log.print_log('系统表对比完成')

        num = 1
        f_path = os.path.join(os.getcwd(), 'log', 'compare',
                              self.upgrade["db_version"],
                              'system_view.diff')
        context = f'{self.upgrade["db_version"]} vs ' \
            f'直接安装{self.direct["db_version"]}\n\n'
        for row in data_dict.get('system_view', None):
            cmd = row.get('cmd', None)
            diff = row.get('diff', None)
            if len(diff) > 0:
                context += cmd + '\n'
                for j in diff:
                    context += str(j) + '\n'
                context += '\n\n'
        self.log.write_file_with_part(f_path, num, context)
        self.log.print_log('系统视图对比完成')

    def compare_meta(self):
        cw = compare_meta_cmd.CompareWrite()
        data_dict = {'system_table': [],
                     'system_view': [],
                     'meta_cmd': []}

        self.log.print_log('开始执行元命令')
        command = '\\?'
        res = cw.run_meta_cmd_and_compare(command, self.upgrade, self.direct)
        data_dict['meta_cmd'].append(res)

        command = '\\copyright'
        res = cw.run_meta_cmd_and_compare(command, self.upgrade, self.direct)
        data_dict['meta_cmd'].append(res)

        # 因\g指定文件路径后，只能在同一session中生效，所以无法验证查询写入的情况
        f_path = f'/home/test_g'
        command = f'> {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)
        command = f'\\g {f_path}'
        res = cw.run_meta_cmd_and_compare(command, self.upgrade, self.direct)
        data_dict['meta_cmd'].append(res)
        command = f'rm -rf {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)

        for c in ('\\h', '\\help', '\\h *', '\\help *'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        for c in ('\\parallel', '\\parallel on', '\\parallel on 2',
                  '\\parallel off'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        command = '\\q'
        res = cw.run_meta_cmd_and_compare(command, self.upgrade, self.direct)
        data_dict['meta_cmd'].append(res)

        f_path = f'/home/test_e'
        command = f'echo "111111"> {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)
        command = f'\\e {f_path}'
        res = cw.run_meta_cmd_and_compare(command, self.upgrade, self.direct)
        data_dict['meta_cmd'].append(res)
        command = f'rm -rf {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)

        for c in ('\\ef ', '\\p ', '\\r '):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)
        create_func = f'create function func_add_sql(' \
            f'num1 integer, num2 integer) ' \
            f'return integer as ' \
            f'begin ' \
            f'return num1 + num2;' \
            f'end;'
        cw.conn_and_run(create_func, True, **self.upgrade)
        cw.conn_and_run(create_func, True, **self.direct)
        for c in ('\\sf func_add_sql', '\\sf+ func_add_sql',
                  '\\ef func_add_sql'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)
        drop_func = f'drop function func_add_sql;'
        cw.conn_and_run(drop_func, True, **self.upgrade)
        cw.conn_and_run(drop_func, True, **self.direct)

        f_path = '/home/test_w'
        command = f'mkdir {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)
        command = '\\w /home/test_w'
        res = cw.run_meta_cmd_and_compare(command, self.upgrade, self.direct)
        data_dict['meta_cmd'].append(res)
        command = f'rm -rf {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)

        create_table = f"drop table if exists t_test_copy;" \
            f"create table t_test_copy(a int, b varchar2(10));" \
            f"insert into t_test_copy values(1,'aa'),(2,'bb');"
        cw.conn_and_run(create_table, True, **self.upgrade)
        cw.conn_and_run(create_table, True, **self.direct)
        f_path = '/home/test_copy_table.csv'
        command = f'\\copy t_test_copy to {f_path}'
        res = cw.run_meta_cmd_and_compare(command, self.upgrade, self.direct)
        data_dict['meta_cmd'].append(res)
        drop_table = f'drop table t_test_copy;'
        cw.conn_and_run(drop_table, True, **self.upgrade)
        cw.conn_and_run(drop_table, True, **self.direct)
        command = f'rm -rf {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)

        f_path = '/home/test_file'
        command = f'echo "select * from pg_user;" > {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)
        for c in ('\\echo "testing"', '\\qecho test ok', f'\\i {f_path}',
                  f'\\ir {f_path}', f'\\o {f_path}'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)
        command = f'rm -rf {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)

        # 使用gs_dump工具导出一个加密文件
        f_path = '/home/expect_file'
        create_table = f"drop table if exists table_test;" \
            f"create table table_test(a int, b varchar2(10));"
        cw.conn_and_run(create_table, True, **self.upgrade)
        cw.conn_and_run(create_table, True, **self.direct)
        command = f'source {self.upgrade["db_env"]};' \
            f'gs_dump -p {self.upgrade["db_port"]} postgres -f {f_path} ' \
            f'-t table_test --with-encryption=AES128 --with-key=testing@123'
        cw.conn_and_run(command, True, **self.upgrade)
        command = f'source {self.direct["db_env"]};' \
            f'gs_dump -p {self.direct["db_port"]} postgres -f {f_path} ' \
            f'-t table_test --with-encryption=AES128 --with-key=testing@123'
        cw.conn_and_run(command, True, **self.direct)
        for c in (f'\\i+ {f_path}', f'\\ir+ {f_path}'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)
        drop_table = f"drop table table_test;"
        cw.conn_and_run(drop_table, True, **self.upgrade)
        cw.conn_and_run(drop_table, True, **self.direct)
        command = f'rm -rf {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)
        cw.conn_and_run(command, False, **self.direct)

        # 显示信息元命令
        create_table = f"drop table if exists t_test_d;" \
            f"create table t_test_d(a int, b varchar2(10));"
        cw.conn_and_run(create_table, True, **self.upgrade)
        cw.conn_and_run(create_table, True, **self.direct)
        for c in ('\\d', '\\dS+ ', '\\d t_test_d', '\\dS+ t_test_d',
                  '\\d+', '\\dS ', '\\d+ t_test_d', '\\dS t_test_d'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)
        drop_table = f'drop table t_test_d;'
        cw.conn_and_run(drop_table, True, **self.upgrade)
        cw.conn_and_run(drop_table, True, **self.direct)

        for c in ('\\da', '\\daS', '\\da f*', '\\daS f*',
                  '\\db', '\\db+', '\\db p*', '\\db+ p*',
                  '\\dc', '\\dcS', '\\dc+', '\\dcS+',
                  '\\dc a*', '\\dc+ a*', '\\dcS a*', '\\dcS+ a*',
                  '\\dC', '\\dC+', '\dC o*', '\dC+ o*',
                  '\\dd', '\\ddS', '\ddp', '\\dD', '\\dDS', '\\dD+',
                  '\\dDS+', '\\ded', '\\ded+', '\\det', '\\det+',
                  '\\des', '\\des+', '\\des g*', '\\des g*', '\\deu',
                  '\\deu+', '\\dew', '\\dew+', '\\dew d*', '\\dew+ d*'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        for c in ('\\df', '\\dfS ', '\\dfS+', '\\df antf', '\\df antfS+',
                  '\\df a*', '\\dfS a*', '\\dfS+ a*', '\\df antf a*',
                  '\\df antfS+ a*', '\\dF', '\\dF+', '\\dF s*', '\\dF+ s*',
                  '\\dFd', '\\dFd+', '\\dFd s*', '\\dFd+ s*',
                  '\\dFp', '\\dFp+', '\\dFp s*', '\\dFp+ s*',
                  '\\dFp', '\\dFp+', '\\dFp n*', '\\dFp+ n*',
                  '\\dg', '\\dg+', '\\dg t*', '\\dg+ t*',
                  '\\di', '\\di+', '\\diS+', '\\diS', '\\diS+ s*',
                  '\\diS s*'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        for c in ('\\dl', '\\dL ', '\\dL+', '\\dLS', '\\dLS+',
                  '\\dL j*', '\\dL+ j*', '\\dLS j*', '\\dLS+ j*',
                  '\\dm ', '\\dm+', '\\dmS', '\\dmS+',
                  '\\dm j*', '\\dm+ j*', '\\dmS j*', '\\dmS+ j*',
                  '\\dn ', '\\dn+', '\\dnS', '\\dnS+',
                  '\\dn d*', '\\dn+ d*', '\\dnS d*', '\\dnS+ d*',
                  '\\do ', '\\doS', '\\do #', '\\doS #',
                  '\\dO', '\\dO+', '\\dOS', '\\dOS+',
                  '\\dO d*', '\\dO+ d*', '\\dOS d*', '\\dOS+ d*',):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        for c in ('\\dp', '\\dp t*', '\\drds', '\\drds * postgres',
                  '\\ds', '\\ds+', '\\dsS', '\\dsS+',
                  '\\dt', '\\dt+', '\\dtS', '\\dtS+',
                  '\\dt t*', '\\dt+ t*', '\\dtS t*', '\\dtS+ t*',
                  '\\dT', '\\dT+', '\\dTS', '\\dTS+',
                  '\\dT b*', '\\dT+ b*', '\\dTS b*', '\\dTS+ b*',
                  '\\du', '\\du+', '\\du u*', '\\du+ u*',
                  '\\dv', '\\dv+', '\\dvS', '\\dvS+',
                  '\\dv p*', '\\dv+ p*', '\\dvS p*', '\\dvS+ p*',
                  '\\dE', '\\dE+', '\\dES', '\\dES+',
                  '\\dx', '\\dx+', '\\dx d*', '\\dx+ d*',
                  '\\l', '\\l+', '\\z', '\\z t*'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        # 格式化元命令
        for c in ('\\a', '\\C', '\\C test_title', '\\f',
                  '\\f field_separator', '\\f |', '\\H'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)
        for c in ('\\pset border 1', '\\pset expanded', '\\pset fieldsep',
                  '\\pset fieldsep_zero', '\\pset footer', '\\pset format u',
                  '\\pset format a', '\\pset null', '\\pset numericlocale',
                  '\\pset numericlocale on', '\\pset numericlocale off',
                  '\\pset pager', '\\pset pager on', '\\pset pager always',
                  '\\pset pager off', '\\pset recordsep',
                  '\\pset recordsep_zero',
                  '\\pset tableattr', '\\pset title', '\\pset tuples_only',
                  '\\t', '\\t on', '\\t off', '\\T',
                  '\\x', '\\x on', '\\x off', '\\x auto',):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        # 连接元命令
        for c in ('\\c template0', '\\c postgres',
                  '\\encoding', '\\encoding UTF8', '\\conninfo'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        # 操作系统元命令
        for c in ('\\cd /home', '\\setenv JAVA', '\\timing ',
                  '\\timing on', '\\timing off', '\\! ls -ld /home'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        # 操作系统元命令
        # 遗留问题：交互式元命令，暂无法实现'\\prompt var_name', '\\prompt text var_name'
        for c in ('\\set a 1', '\\set b', '\\unset a',
                  '\\set verbosity default', '\\set verbosity verbose',
                  '\\set verbosity terse', '\\set on_error_stop on',
                  '\\set on_error_stop off', '\\set retry 6'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)

        # 大对象元命令
        f_path = '/home/test_file'
        command = f'echo "select * from pg_user;" > {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)
        for c in (f'\\lo_import {f_path}', f'\\lo_export loboid {f_path}',
                  '\\lo_list', '\\lo_unlink loboid'):
            res = cw.run_meta_cmd_and_compare(c, self.upgrade, self.direct)
            data_dict['meta_cmd'].append(res)
        command = f'rm -rf {f_path}'
        cw.conn_and_run(command, False, **self.upgrade)

        n = 1
        f_path = os.path.join(os.getcwd(), 'log', 'compare',
                              self.upgrade["db_version"],
                              'meta_cmd.diff')
        context = f'{self.upgrade["db_version"]} vs ' \
            f'直接安装{self.direct["db_version"]}\n\n'
        for row in data_dict.get('meta_cmd', None):
            cmd = row.get('cmd', None)
            differ = row.get('diff', None)
            if len(differ) > 0:
                context += cmd + '\n'
                for j in differ:
                    context += str(j) + '\n'
                context += '\n\n'
        self.log.write_file_with_part(f_path, n, context)

        self.log.print_log('执行元命令完成')

    def init_compare_data(self, init_user, db_user, db_pwd, db_name, db_port,
                          db_vesion):
        db_info = {'init_user': init_user,
                   'db_user': db_user,
                   'password': db_pwd,
                   'database': db_name,
                   'port': db_port,
                   'env_path': os.path.join('/', 'home', init_user,
                                            'gaussdb.bashrc'),
                   'db_version': db_vesion}
        self.cda = CompareData(**db_info)

    def get_table_data(self, fname):
        self.log.print_log('读取表数据')
        self.cda.get_tables()
        self.cda.get_checksum()
        self.cda.write_checksum_to_file(fname)
        self.log.print_log('读取表数据完成')

    def set_tpcc_props(self, db_host, db_port, db_name, db_user, db_pwd,
                       p_name='props.pg'):
        self.log.print_log('配置benchmark配置文件')
        cmd = f"cd {self.tpcc_path} && " \
            f"sed -i '3cconn=jdbc:postgresql://{db_host}:{db_port}/" \
            f"{db_name}' {p_name} && " \
            f"sed -i '4cuser={db_user}' {p_name} && " \
            f"sed -i '5cpassword={db_pwd}' {p_name}"
        try:
            self.log.print_log(cmd.replace(db_pwd, '******'))
            res = subprocess.getoutput(cmd)
        except Exception as e:
            self.log.print_log(f'配置benchmark配置文件失败，ERROR: {str(e)}')
        else:
            self.log.print_log(res)
            self.log.print_log('配置benchmark配置文件完成')

    def run_tpcc(self, mode='run', p_name='props.pg'):
        self.log.print_log(f'开始执行benchmark-{mode}')
        if mode == 'run':
            s_name = 'runBenchmark.sh'
        elif mode == 'build':
            s_name = 'runDatabaseBuild.sh'
        else:
            s_name = 'runDatabaseDestroy.sh'
        cmd = f"cd {self.tpcc_path} && sh {s_name} {p_name}"
        try:
            self.log.print_log(cmd)
            res = subprocess.getoutput(cmd)
        except Exception as e:
            self.log.print_log(f'执行benchmark-{mode}失败，ERROR: {str(e)}')
        else:
            self.log.print_log(res)
            self.log.print_log(f'执行benchmark-{mode}成功')

    # 直接升级：灰度升级场景
    def direct_grey(self, upgrade_prefix, direct_prefix, low_ftp_path,
                    high_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'灰度升级{self.up.befor_version}直接升级到{self.up.after_version}')
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path)

        self.log.print_log('直接安装数据库造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.direct['ip'], self.direct['db_port'],
                            self.direct['db_name'], 'tpccuser',
                            self.direct['pwd'], self.di_tpcc_pname)
        self.run_tpcc('build', self.di_tpcc_pname)
        self.run_tpcc('run', self.di_tpcc_pname)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()

        self.log.print_log('升级后验证业务运行正常')
        self.run_tpcc('run', self.up_tpcc_pname)

    # 直接升级：就地升级场景
    def direct(self, upgrade_prefix, direct_prefix, low_ftp_path,
               high_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'就地升级{self.up.befor_version}直接升级到{self.up.after_version}')
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path)

        self.log.print_log('直接安装数据库造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.direct['ip'], self.direct['db_port'],
                            self.direct['db_name'], 'tpccuser',
                            self.direct['pwd'], self.di_tpcc_pname)
        self.run_tpcc('build', self.di_tpcc_pname)
        self.run_tpcc('run', self.di_tpcc_pname)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()

        self.log.print_log('升级后验证业务运行正常')
        self.run_tpcc('run', self.up_tpcc_pname)

    # 直接升级：灰度升级后回滚场景
    def direct_grey_rollback(self, upgrade_prefix, direct_prefix,
                             low_ftp_path, high_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.direct['db_version'] = self.up.befor_version
        self.log.print_log(
            f'灰度升级{self.up.befor_version}直接升级到{self.up.after_version}再回滚')
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.rollback('', 'Rollback succeeded')

        self.log.print_log(f'升级回滚后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装低版本{self.up.befor_version}')
        self.install(direct_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log('直接安装数据库造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.direct['ip'], self.direct['db_port'],
                            self.direct['db_name'], 'tpccuser',
                            self.direct['pwd'], self.di_tpcc_pname)
        self.run_tpcc('build', self.di_tpcc_pname)
        self.run_tpcc('run', self.di_tpcc_pname)

        self.log.print_log('升级回滚vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级回滚vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级回滚vs直接安装对比：业务数据')
        self.cda.compare()

        self.log.print_log('升级回滚后验证业务运行正常')
        self.run_tpcc('run', self.up_tpcc_pname)

    # 直接升级：就地升级后回滚场景
    def direct_rollback(self, upgrade_prefix, direct_prefix,
                        low_ftp_path, high_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.direct['db_version'] = self.up.befor_version
        self.log.print_log(
            f'就地升级{self.up.befor_version}直接升级到{self.up.after_version}再回滚')
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.rollback('', 'Rollback succeeded')

        self.log.print_log(f'升级回滚后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装低版本{self.up.befor_version}')
        self.install(direct_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log('直接安装数据库造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.direct['ip'], self.direct['db_port'],
                            self.direct['db_name'], 'tpccuser',
                            self.direct['pwd'], self.di_tpcc_pname)
        self.run_tpcc('build', self.di_tpcc_pname)
        self.run_tpcc('run', self.di_tpcc_pname)

        self.log.print_log('升级回滚vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级回滚vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级回滚vs直接安装对比：业务数据')
        self.cda.compare()

        self.log.print_log('升级回滚后验证业务运行正常')
        self.run_tpcc('run', self.up_tpcc_pname)

    # 直接升级：灰度升级后强制回滚场景
    def direct_grey_force_rollback(self, upgrade_prefix, direct_prefix,
                                   low_ftp_path, high_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.direct['db_version'] = self.up.befor_version
        self.log.print_log(
            f'灰度升级{self.up.befor_version}直接升级到{self.up.after_version}再强制回滚')
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.rollback('--force', 'Rollback succeeded')

        self.log.print_log(f'升级强制回滚后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装低版本{self.up.befor_version}')
        self.install(direct_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log('直接安装数据库造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.direct['ip'], self.direct['db_port'],
                            self.direct['db_name'], 'tpccuser',
                            self.direct['pwd'], self.di_tpcc_pname)
        self.run_tpcc('build', self.di_tpcc_pname)
        self.run_tpcc('run', self.di_tpcc_pname)

        self.log.print_log('升级强制回滚vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级强制回滚vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级强制回滚vs直接安装对比：业务数据')
        self.cda.compare()

        self.log.print_log('升级强制回滚后验证业务运行正常')
        self.run_tpcc('run', self.up_tpcc_pname)

    # 直接升级：就地升级后强制回滚场景
    def direct_force_rollback(self, upgrade_prefix, direct_prefix,
                              low_ftp_path, high_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.direct['db_version'] = self.up.befor_version
        self.log.print_log(
            f'就地升级{self.up.befor_version}直接升级到{self.up.after_version}再强制回滚')
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.rollback('--force', 'Rollback succeeded')

        self.log.print_log(f'升级强制回滚后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装低版本{self.up.befor_version}')
        self.install(direct_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log('直接安装数据库造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.direct['ip'], self.direct['db_port'],
                            self.direct['db_name'], 'tpccuser',
                            self.direct['pwd'], self.di_tpcc_pname)
        self.run_tpcc('build', self.di_tpcc_pname)
        self.run_tpcc('run', self.di_tpcc_pname)

        self.log.print_log('升级强制回滚vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级强制回滚vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级强制回滚vs直接安装对比：业务数据')
        self.cda.compare()

        self.log.print_log('升级强制回滚后验证业务运行正常')
        self.run_tpcc('run', self.up_tpcc_pname)

    # 直接升级：CM安装数据库灰度升级CM数据库场景
    def direct_grey_cm_cm(self, upgrade_prefix, direct_prefix, low_ftp_path,
                          high_ftp_path):
        self.log.print_log(f'安装cm低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path,
                     cm_flag=True)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'灰度升级{self.up.befor_version}直接升级到{self.up.after_version}')
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.up.check_befor_upgrade(cm_flag=True)
        self.up.do_upgrade('--grey', cm_flag=True)
        self.up.after_upgrade(cm_flag=True)
        self.up.commit_upgrage()
        self.up.after_upgrade(cm_flag=True)

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装cm高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path,
                     cm_flag=True)

        self.log.print_log('直接安装数据库造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.direct['ip'], self.direct['db_port'],
                            self.direct['db_name'], 'tpccuser',
                            self.direct['pwd'], self.di_tpcc_pname)
        self.run_tpcc('build', self.di_tpcc_pname)
        self.run_tpcc('run', self.di_tpcc_pname)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()

        self.log.print_log('升级后验证业务运行正常')
        self.run_tpcc('run', self.up_tpcc_pname)

    # 直接升级：非CM安装数据库灰度升级CM数据库场景
    def direct_grey_ncm_cm(self, upgrade_prefix, direct_prefix,
                           low_ftp_path, high_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级cm高版本')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'灰度升级{self.up.befor_version}直接升级到{self.up.after_version}')
        self.ins.update_xml_for_cm(**self.hosts)
        self.up.ftp_path = high_ftp_path
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade(cm_flag=True)
        self.up.commit_upgrage()
        self.up.after_upgrade(cm_flag=True)

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装cm高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path,
                     cm_flag=True)

        self.log.print_log('直接安装数据库造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.direct['ip'], self.direct['db_port'],
                            self.direct['db_name'], 'tpccuser',
                            self.direct['pwd'], self.di_tpcc_pname)
        self.run_tpcc('build', self.di_tpcc_pname)
        self.run_tpcc('run', self.di_tpcc_pname)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()

        self.log.print_log('升级后验证业务运行正常')
        self.run_tpcc('run', self.up_tpcc_pname)

    # 间接升级：灰度升级场景
    def indirect_grey(self, upgrade_prefix, direct_prefix, low_ftp_path,
                      high_ftp_path, middle_version, mid_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'灰度升级{self.up.befor_version}先升级到{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_version = self.up.after_version
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(
            f'灰度升级{middle_version}再升级到{tmp_version}')
        self.up.ftp_path = high_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()

    # 间接升级：就地升级场景
    def indirect(self, upgrade_prefix, direct_prefix, low_ftp_path,
                 high_ftp_path, middle_version, mid_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'就地升级{self.up.befor_version}先升级到{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_ftp_path = self.up.ftp_path
        tmp_version = self.up.after_version
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(
            f'就地升级{middle_version}再升级到{tmp_version}')
        self.up.ftp_path = tmp_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()

    # 间接升级：灰度升级后回滚场景
    def indirect_grey_rollback(self, upgrade_prefix, direct_prefix,
                               low_ftp_path, high_ftp_path, middle_version,
                               mid_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'灰度升级{self.up.befor_version}先升级到{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_version = self.up.after_version
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(
            f'灰度升级{middle_version}再升级到{tmp_version}后回滚')
        self.up.ftp_path = high_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.rollback('', 'Rollback succeeded')

        self.log.print_log(f'回滚后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级回滚vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级回滚vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级回滚vs直接安装对比：业务数据')
        self.cda.compare()

    # 间接升级：灰度升级后强制回滚场景
    def indirect_grey_force_rollback(self, upgrade_prefix, direct_prefix,
                                     low_ftp_path, high_ftp_path,
                                     middle_version, mid_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'灰度升级{self.up.befor_version}先升级到{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_version = self.up.after_version
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(
            f'灰度升级{middle_version}再升级到{tmp_version}后强制回滚')
        self.up.ftp_path = high_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.rollback('--force', 'Rollback succeeded')

        self.log.print_log(f'回滚后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级回滚vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级回滚vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级回滚vs直接安装对比：业务数据')
        self.cda.compare()

    # 间接升级：就地升级后回滚场景
    def indirect_rollback(self, upgrade_prefix, direct_prefix, low_ftp_path,
                          high_ftp_path, middle_version, mid_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'就地升级{self.up.befor_version}先升级到{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_version = self.up.after_version
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(
            f'就地升级{middle_version}再升级到{tmp_version}后回滚')
        self.up.ftp_path = high_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.rollback('', 'Rollback succeeded')

        self.log.print_log(f'回滚后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级回滚vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级回滚vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级回滚vs直接安装对比：业务数据')
        self.cda.compare()

    # 间接升级：就地升级后强制回滚场景
    def indirect_force_rollback(self, upgrade_prefix, direct_prefix,
                                low_ftp_path, high_ftp_path, middle_version,
                                mid_ftp_path):
        self.log.print_log(f'安装低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'就地升级{self.up.befor_version}先升级到{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_version = self.up.after_version
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(
            f'就地升级{middle_version}再升级到{tmp_version}后强制回滚')
        self.up.ftp_path = high_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('')
        self.up.after_upgrade()
        self.up.rollback('--force', 'Rollback succeeded')

        self.log.print_log(f'回滚后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级强制回滚vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级强制回滚vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级强制回滚vs直接安装对比：业务数据')
        self.cda.compare()

    # 间接升级：cm-cm-cm灰度升级场景
    def indirect_grey_upgrade_cm_cm_cm(self, upgrade_prefix, direct_prefix,
                                       low_ftp_path, high_ftp_path,
                                       middle_version, mid_ftp_path):
        self.log.print_log(f'安装cm低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path,
                     cm_flag=True)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'cm灰度升级{self.up.befor_version}先升级到{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_version = self.up.after_version
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade(cm_flag=True)
        self.up.do_upgrade('--grey', cm_flag=True)
        self.up.after_upgrade(cm_flag=True)
        self.up.commit_upgrage()
        self.up.after_upgrade(cm_flag=True)

        self.log.print_log(
            f'cm灰度升级{middle_version}再升级到{tmp_version}')
        self.up.ftp_path = high_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade(cm_flag=True)
        self.up.do_upgrade('--grey', cm_flag=True)
        self.up.after_upgrade(cm_flag=True)
        self.up.commit_upgrage()
        self.up.after_upgrade(cm_flag=True)

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装cm高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path,
                     cm_flag=True)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()

    # 间接升级：非cm-cm-cm灰度升级场景
    def indirect_grey_upgrade_ncm_cm_cm(self, upgrade_prefix, direct_prefix,
                                        low_ftp_path, high_ftp_path,
                                        middle_version, mid_ftp_path):
        self.log.print_log(f'安装非cm低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'非cm灰度升级{self.up.befor_version}先升级到cm{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_version = self.up.after_version
        self.ins.update_xml_for_cm(**self.hosts)
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade(cm_flag=True)
        self.up.commit_upgrage()
        self.up.after_upgrade(cm_flag=True)

        self.log.print_log(
            f'cm灰度升级{middle_version}再升级到cm{tmp_version}')
        self.up.ftp_path = high_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade(cm_flag=True)
        self.up.do_upgrade('--grey', cm_flag=True)
        self.up.after_upgrade(cm_flag=True)
        self.up.commit_upgrage()
        self.up.after_upgrade(cm_flag=True)

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装cm高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path,
                     cm_flag=True)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()

        self.run_tpcc('run', self.up_tpcc_pname)

    # 间接升级：非cm-非cm-cm灰度升级场景
    def indirect_grey_upgrade_ncm_ncm_cm(self, upgrade_prefix, direct_prefix,
                                         low_ftp_path, high_ftp_path,
                                         middle_version, mid_ftp_path):
        self.log.print_log(f'安装非cm低版本{self.up.befor_version}用来升级')
        self.install(upgrade_prefix, self.up.befor_version, low_ftp_path)

        self.log.print_log(f'升级前造数据')
        self.set_params(upgrade_prefix, direct_prefix)
        self.set_tpcc_props(self.upgrade['ip'], self.upgrade['db_port'],
                            self.upgrade['db_name'], 'tpccuser',
                            self.upgrade['pwd'], self.up_tpcc_pname)
        self.run_tpcc('build', self.up_tpcc_pname)
        self.run_tpcc('run', self.up_tpcc_pname)

        self.log.print_log(f'升级前读取业务数据')
        self.init_compare_data(self.upgrade['username'],
                               'tpccuser',
                               self.upgrade['pwd'],
                               self.upgrade['db_name'],
                               self.upgrade['db_port'],
                               self.upgrade['db_version'])
        self.get_table_data('before_upgrade')

        self.log.print_log(
            f'非cm灰度升级{self.up.befor_version}先升级到非cm{middle_version}')
        self.set_params(upgrade_prefix, direct_prefix)
        tmp_version = self.up.after_version
        self.up.ftp_path = mid_ftp_path
        self.up.after_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade()
        self.up.commit_upgrage()
        self.up.after_upgrade()

        self.log.print_log(
            f'非cm灰度升级{middle_version}再升级到cm{tmp_version}')
        self.ins.update_xml_for_cm(**self.hosts)
        self.up.ftp_path = high_ftp_path
        self.up.after_version = tmp_version
        self.up.befor_version = middle_version
        self.up.set_params()
        self.up.check_befor_upgrade()
        self.up.do_upgrade('--grey')
        self.up.after_upgrade(cm_flag=True)
        self.up.commit_upgrage()
        self.up.after_upgrade(cm_flag=True)

        self.log.print_log(f'升级后读取业务数据')
        self.get_table_data('after_upgrade')

        self.log.print_log(f'直接安装cm高版本版本{self.up.after_version}')
        self.install(direct_prefix, self.up.after_version, high_ftp_path,
                     cm_flag=True)
        self.set_params(upgrade_prefix, direct_prefix)

        self.log.print_log('升级vs直接安装对比：系统表&&系统视图')
        self.compare_sys()

        self.log.print_log('升级vs直接安装对比：元命令')
        self.compare_meta()

        self.log.print_log('升级vs直接安装对比：业务数据')
        self.cda.compare()


if __name__ == '__main__':
    if len(sys.argv) < 17:
        raise Exception('请检查入参数量！')
    up_params = dict()
    up_params['userpasswd'] = sys.argv[1]
    up_params['upgrade_ftp_path'] = sys.argv[2]
    up_params['upgrade_user_prefix'] = sys.argv[3]
    up_params['prefixPort'] = sys.argv[4]
    up_params['db_root_path'] = sys.argv[5]
    up_params['pkg_root_path'] = sys.argv[6]
    up_params['ipaddress'] = sys.argv[7]
    up_params['ipaddress_std1'] = sys.argv[8]
    up_params['ipaddress_std2'] = sys.argv[9]
    up_params['tpcc_path'] = sys.argv[16]
    hostnames = (sys.argv[10], sys.argv[11], sys.argv[12])

    command = 'rm -rf log/*; ' \
              'mkdir -p up_direct_log/success_log;' \
              'mkdir -p up_direct_log/error_log;'
    subprocess.getoutput(command)

    up_params['befor_version'] = sys.argv[13]
    up_params['after_version'] = sys.argv[14]
    up = UpgradeScene(*hostnames, **up_params)
    low_path = sys.argv[15]
    high_path = up_params['upgrade_ftp_path']
    up.log.print_log(f'灰度升级{up_params["befor_version"]}-->'
                     f'{up_params["after_version"]}')
    up.grey_upgrade('upgrade_1_', 'upgrade_2_', low_path, high_path)
    res = subprocess.getoutput(
        f'mv log success_log/灰度升级{up_params["befor_version"]}~'
        f'{up_params["after_version"]}_log')
    up.log.print_log(res)

    mid_version = '2.0.1'
    mid_path = "ftp://ftp.opengauss.inhuawei.com/upgrade/CentOS7.6/" \
               "openGauss-2.0.1-CentOS-64bit-all.tar.gz"
    up.indirect_grey('upgrade_1_', 'upgrade_2_', low_path, high_path,
                     mid_version, mid_path)
    up.log.print_log('灰度间接升级完成')

    mid_version = '3.0.1'
    mid_path = "ftp://ftp.opengauss.inhuawei.com/upgrade/inplace_upgrade/" \
               "openGauss_3.0.1_PACKAGES_RELEASE.tar.gz"
    up.indirect('upgrade_1_', 'upgrade_2_', low_path, high_path,
                mid_version, mid_path)
    up.log.print_log('就地间接升级完成')

    mid_version = '3.0.0'
    mid_path = "ftp://ftp.opengauss.inhuawei.com/upgrade/CentOS7.6/" \
               "openGauss-3.0.0-CentOS-64bit-all.tar.gz"
    up.indirect_grey_upgrade_cm_cm_cm('upgrade_1_', 'upgrade_2_', low_path,
                                      high_path, mid_version, mid_path)
    up.log.print_log('灰度：CM-CM-CM升级完成')

    mid_version = '2.0.4'
    mid_path = "ftp://ftp.opengauss.inhuawei.com/upgrade/CentOS7.6/" \
               "openGauss-2.0.4-CentOS-64bit-all.tar.gz"
    up.indirect_grey_upgrade_ncm_cm_cm('upgrade_1_', 'upgrade_2_', low_path,
                                       high_path, mid_version, mid_path)
    up.log.print_log('灰度：NCM-CM-CM升级完成')

    mid_version = '2.0.1'
    mid_path = "ftp://ftp.opengauss.inhuawei.com/upgrade/CentOS7.6/" \
               "openGauss-2.0.1-CentOS-64bit-all.tar.gz"
    up.indirect_grey_upgrade_ncm_ncm_cm('upgrade_1_', 'upgrade_2_', low_path,
                                        high_path, mid_version, mid_path)
    up.log.print_log('灰度：NCM-NCM-CM升级完成')
